package com.beemans.corekit.integration.topon;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LifecycleOwner;

import com.anythink.core.api.ATAdInfo;
import com.anythink.core.api.AdError;
import com.anythink.rewardvideo.api.ATRewardVideoAd;
import com.anythink.rewardvideo.api.ATRewardVideoListener;

public class RewardAdvert extends BaseAdvert implements ATRewardVideoListener {
    @NonNull
    private final LifecycleOwner lifecycleOwner;
    @NonNull
    private final RewardAdvertConfig advertConfig;
    @Nullable
    private final FragmentActivity fragmentActivity;
    @Nullable
    private ATRewardVideoAd atRewardVideoAd;
    @Nullable
    private RewardAdvertCallback advertCallback;

    private boolean isAdvertReward;
    private boolean isAdvertLoadFailed = false;

    public RewardAdvert(
            @NonNull LifecycleOwner lifecycleOwner,
            @NonNull RewardAdvertConfig advertConfig
    ) {
        this(lifecycleOwner, advertConfig, null);
    }

    public RewardAdvert(
            @NonNull LifecycleOwner lifecycleOwner,
            @NonNull RewardAdvertConfig advertConfig,
            @Nullable RewardAdvertCallback advertCallback
    ) {
        this.lifecycleOwner = lifecycleOwner;
        this.advertConfig = advertConfig;
        this.advertCallback = advertCallback;
        this.fragmentActivity = AdvertLifeUtils.getContext(lifecycleOwner);

        if (fragmentActivity == null) {
            return;
        }

        atRewardVideoAd = new ATRewardVideoAd(fragmentActivity, advertConfig.getPlacementId());
        atRewardVideoAd.setAdListener(this);
        atRewardVideoAd.setAdRevenueListener(atAdInfo -> {
            if (advertCallback != null) {
                advertCallback.onAdvertRevenue(this, atAdInfo);
            }
        });

        AdvertLifeUtils.launchWhenDestroy(lifecycleOwner, this::onAdvertRelease);

        if (advertCallback != null) {
            advertCallback.onAdvertStart(this);
        }
    }

    /**
     * @return 广告是否已下发奖励
     * @noinspection unused
     */
    public boolean isAdvertReward() {
        return isAdvertReward;
    }

    /**
     * @return 广告是否准备完毕
     */
    @Override
    public boolean isAdvertReady() {
        if (atRewardVideoAd == null) {
            return false;
        }
        return atRewardVideoAd.isAdReady();
    }

    /**
     * @return 广告是否正在加载
     */
    @Override
    public boolean isAdvertLoading() {
        if (atRewardVideoAd == null) {
            return false;
        }
        return atRewardVideoAd.checkAdStatus().isLoading();
    }

    /**
     * 加载广告
     */
    @Override
    protected void loadAdvert() {
        loadAdvert(false);
    }

    @Override
    public void onAdvertRelease() {
        super.onAdvertRelease();

        if (advertCallback != null) {
            advertCallback = null;
        }
        if (atRewardVideoAd != null) {
            try {
                atRewardVideoAd.setAdListener(null);
                atRewardVideoAd.setAdDownloadListener(null);
                atRewardVideoAd.setAdSourceStatusListener(null);
            } catch (Throwable ignored) {
            }
            atRewardVideoAd = null;
        }
    }

    private void loadAdvert(boolean isPreloadAdvert) {
        isAdvertReward = false;
        isAdvertLoadFailed = false;

        if (atRewardVideoAd == null) {
            return;
        }
        if ((!isPreloadAdvert || !advertConfig.isPreloadWithoutReady()) && isAdvertReady()) {
            onAdvertLoaded(false);
            return;
        }

        setTimeout(advertConfig.getTimeoutMillis(), () -> {
            onAdvertLoadFail(AdvertConstants.ERR_TIMEOUT_DESC);
            onAdvertRelease();
        });

        waitForAdvertToLoad(() -> {
            if (isAdvertReady()) {
                onAdvertLoaded(false);
                return;
            }
            if (atRewardVideoAd != null) {
                onAdvertRequestPre();

                try {
                    atRewardVideoAd.load();
                } catch (Throwable throwable) {
                    onAdvertLoadFail(throwable.getMessage());
                }
            }
        });
    }

    /**
     * 展示广告
     */
    private void showAdvert() {
        if (fragmentActivity == null) {
            return;
        }
        AdvertLifeUtils.launchWhenResume(lifecycleOwner, () -> {
            if (!isAdvertReady()) {
                onAdvertShowFail();
                return;
            }
            if (atRewardVideoAd != null) {
                try {
                    atRewardVideoAd.show(fragmentActivity);
                } catch (Throwable ignored) {
                    onAdvertShowFail();
                }
            }
        });
    }

    private void onAdvertShowFail() {
        if (advertCallback != null) {
            advertCallback.onAdvertShowFail(this);
        }
    }

    private void onAdvertRequestPre() {
        if (advertCallback != null) {
            final ATAdInfoExt adInfoExt = new ATAdInfoExt();
            adInfoExt.adunit_id = advertConfig.getPlacementId();
            adInfoExt.adunit_format = AdUnitFormat.NATIVE.getValue();
            advertCallback.onAdvertRequestPre(this, adInfoExt);
        }
    }

    private void onAdvertRequestAlt() {
        if (advertCallback != null) {
            final ATAdInfoExt adInfoExt = new ATAdInfoExt();
            adInfoExt.adunit_id = advertConfig.getPlacementId();
            adInfoExt.adunit_format = AdUnitFormat.NATIVE.getValue();
            advertCallback.onAdvertRequestAlt(this, adInfoExt);
        }
    }

    private void onAdvertLoaded(boolean adLoadedReal) {
        if (adLoadedReal) {
            onAdvertRequestAlt();
        }
        if (isAdvertLoadFailed) {
            return;
        }

        clearTimeout();

        if (advertCallback != null) {
            advertCallback.onAdvertLoaded(this);
        }
        if (advertConfig.isShowAfterLoaded()) {
            showAdvert();
        }
    }

    private void onAdvertLoadFail(String adError) {
        clearTimeout();

        if (isAdvertLoadFailed) return;
        isAdvertLoadFailed = true;

        if (advertCallback != null) {
            advertCallback.onAdvertLoadFail(this, adError);
        }
    }

    @Override
    public void onRewardedVideoAdLoaded() {
        onAdvertLoaded(true);
    }

    @Override
    public void onRewardedVideoAdFailed(AdError adError) {
        onAdvertLoadFail(adError != null ? adError.toString() : null);
    }

    @Override
    public void onRewardedVideoAdPlayClicked(ATAdInfo atAdInfo) {
        if (advertCallback != null) {
            advertCallback.onAdvertClicked(this, atAdInfo);
        }
    }

    @Override
    public void onRewardedVideoAdClosed(ATAdInfo atAdInfo) {
        if (advertCallback != null) {
            advertCallback.onAdvertClose(this, atAdInfo);
        }

        onAdvertRelease();
    }

    @Override
    public void onRewardedVideoAdPlayStart(ATAdInfo atAdInfo) {
        if (advertCallback != null) {
            advertCallback.onAdvertShow(this, atAdInfo);
        }
        if (advertConfig.isPreloadAdvert()) {
            final RewardAdvertConfig rewardAdvertConfig
                    = AdvertGsonUtils.getInstance().deepClone(advertConfig, RewardAdvertConfig.class);
            if (rewardAdvertConfig != null) {
                rewardAdvertConfig.setShowAfterLoaded(false);

                final RewardAdvert rewardAdvert = new RewardAdvert(lifecycleOwner, rewardAdvertConfig);
                rewardAdvert.loadAdvert(true);
            }
        }
    }

    @Override
    public void onRewardedVideoAdPlayEnd(ATAdInfo atAdInfo) {
    }

    @Override
    public void onRewardedVideoAdPlayFailed(AdError adError, ATAdInfo atAdInfo) {
        onAdvertShowFail();
    }

    @Override
    public void onReward(ATAdInfo atAdInfo) {
        isAdvertReward = true;

        if (advertCallback != null) {
            advertCallback.onAdvertReward(this, atAdInfo);
        }
    }
}
